using System;
using System.Collections.Generic;
using System.Reflection;

namespace BruteMerge.ExecutableLauncher
{
    internal class ApplicationAssemblyLoader
    {
        private readonly Dictionary<string, Assembly> _loadedAssemblyCache = new Dictionary<string, Assembly>();
        private readonly ResourceProvider _resourceProvider;
        private readonly AppDomain _domain;

        private void RegisterResolveHandler()
        {
            _domain.AssemblyResolve += AssemblyResolve;
        }

        public ApplicationAssemblyLoader(ResourceProvider resourceProvider, AppDomain domain)
        {
            _resourceProvider = resourceProvider;
            _domain = domain;

            RegisterResolveHandler();
        }

        private Assembly LoadAsseblyInternal(string assemblyName)
        {
            return _resourceProvider.CanBeLoaded(assemblyName)
                       ? Assembly.Load(_resourceProvider.LoadBytes(assemblyName))
                       : null;
        }

        

       

        public Assembly LoadAssembly(string assemblyName)
        {
            if (_loadedAssemblyCache.ContainsKey(assemblyName))
                return _loadedAssemblyCache[assemblyName];

            var assembly = LoadAsseblyInternal(assemblyName);
            if (assembly!=null) _loadedAssemblyCache.Add(assemblyName, assembly);

            return assembly;
        }

        private Assembly AssemblyResolve(object sender, ResolveEventArgs args)
        {
            var assemblyName = args.Name;

            Debug.Println("Resolving: {0}", assemblyName);

            return LoadAssembly(assemblyName);
        }

    }
}